package utils

import (
	"fmt"
	"strconv"
	"strings"
)

type String string

// 返回字符串
func FromStr(str string) String {
	return String(str)
}

// 返回int
func FromInt(num int) String {
	return String(strconv.Itoa(num))
}

// 获取字符串的长度
func (s String) Len() int {
	return len([]rune(s))
}

// 遍历字符串
func (s String) Each(fn func(item string) )  {
	for _,v := range s {
		fn(fmt.Sprintf("%c",v))
	}
}

// 遍历字符串
func (s String) EachByte(fn func(str byte))  {
	strs := []byte(s)
	for _,c := range strs {
		fn(c)
	}
}

// 首字母大写后面字母保持不变
// example:(helloWorld => HelloWorld)
func (s String) Ufirst() string {
	if s == "" {
		return ""
	}
	// 字符串长度为1直接转换
	if len(s) == 1 {
		return strings.ToUpper(string(s))
	} else {
		return strings.ToUpper(string(s[0])) + string(s[1:])
	}
}

// 首字母大写后面字母全部小写
// example:(helloWorld => Helloworld)
func (s String) UfirstLlater() string {
	if s == "" {
		return ""
	}
	// 字符串长度为1直接转换
	if len(s) == 1 {
		return strings.ToUpper(string(s))
	} else {
		return strings.ToUpper(string(s[0])) + strings.ToLower(string(s[1:]))
	}
}

// 下划线模式
//example: helloWorld => hello_world
//		   helloWorld_A => hello_world_a
func (s String) SnakeCase() string {
	strs := make([]byte, 0, len(s)) // 字节切片，用来收集字符串
	isUnderLine := false // 是否为下划线
	s.EachByte(func(str byte) {
		// 大写字母，前一个字符不为下划线
		if str >= 65 && str <= 90 {
			if isUnderLine == false {
				strs = append(strs, 95) // 添加下划线
			}
		}
		if str == 95 {
			isUnderLine = true
		} else {
			isUnderLine = false
		}
		strs = append(strs, str)
	})
	return strings.ToLower(string(strs[:]))
}

// 驼峰模式
//example: hello_world => helloWorld
//		   hello_world_A => helloWorldA
func (s String) CamelCase() string {
	strs := make([]byte, 0, len(s)) // 字节切片，用来收集字符串
	isToUpper := false // 是否需要转换为大写
	s.EachByte(func(str byte) {
		if str >= 97 && str <= 122 && isToUpper {
			str -= 32
			isToUpper = false
		}
		if str == 95 {
			isToUpper = true
		} else {
			isToUpper = false
			strs = append(strs, str)
		}
	})
	return string(strs[:])
}


